package com.zhangyj.component.tags;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.io.Writer;
import java.util.HashMap;
import java.util.Map;
import java.util.StringTokenizer;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.Tag;
import javax.servlet.jsp.tagext.TagSupport;

import com.zhangyj.action.BoastContext;
import com.zhangyj.cache.CacheEngine;
import com.zhangyj.cache.DataCacheManager;
import com.zhangyj.util.IOTools;
import com.zhangyj.util.Tools;

public class IncludeJS extends TagSupport {
	private static final String cacheName = "JsCache";
	private static CacheEngine cacheEngine = DataCacheManager.getCacheEngine();
	private static final String start = "<script type=\"text/javascript\">";
	private static final String end = "</script>";
	private static boolean isDebug = BoastContext.isDebug();
	private String file;

	public String getFile() {
		return file;
	}

	public void setFile(String file) {
		this.file = file;
	}

	private static final long serialVersionUID = -1510300240871665167L;

	@Override
	public int doStartTag() throws JspException {
		Writer writer = this.pageContext.getOut();
		Reader reader = null;
		try {
			writer.append(start);
			writer.append("var contextPath = \"" + ((HttpServletRequest)pageContext.getRequest()).getContextPath() + "\";\n");
			writer.append(end);
			writer.append(start);
			writerJs(pageContext.getServletContext().getRealPath(file), writer);
			writer.append(end);
		} catch (Exception e) {
			throw new JspException(e);
		} finally {
			if (reader != null) {
				try {
					reader.close();
				} catch (IOException e) {
					throw new JspException(e);
				}
			}
		}
		return Tag.EVAL_BODY_INCLUDE;
	}

	private static void writerJs(String path, Writer writer) throws Exception {
		String js = (String) cacheEngine.getObject(cacheName, path);
		if (js == null) {
			StringBuilder buf = new StringBuilder();
			ByteArrayOutputStream baos = IOTools.readFileToByteStream(new File(path));
			String srcjs = baos.toString("utf-8");
			baos = null;
			int localbegin = srcjs.indexOf("LOCALEMESSAGE_BEGIN");
			int localend = srcjs.indexOf("LOCALEMESSAGE_END");
			if (localbegin != -1 && localend != -1) {
				buf.append(srcjs.substring(0, localbegin));
				buf.append("var _local_msg=").append(buildLocaleMessage(srcjs.substring(localbegin + 19, localend))).append(";");
				buf.append(srcjs.substring(localend + 17));
			} else {
				buf.append("var _local_msg={};");
				buf.append(srcjs);
			}
			js = buf.toString();
			if (isDebug == false) {
				InputStream in = new ByteArrayInputStream(js.getBytes());
				baos = new ByteArrayOutputStream();
				JSMin jsMin = new JSMin(in, baos);
				jsMin.jsmin();
				js = baos.toString();
				cacheEngine.putObject(cacheName, path, js);
			}
		}
		writer.append(js);
	}
	
	private static String buildLocaleMessage(String str) throws Exception {
		Map<String, String> msg = new HashMap<String, String>();
		StringTokenizer stk = new StringTokenizer(str);
		while (stk.hasMoreTokens()) {
			String item = stk.nextToken();
			int index = item.indexOf(':');
			if (index > 0)
				msg.put(item.substring(0, index), item.substring(index+1));
			else
				msg.put(item, item);
		}
		return Tools.object2jsonStr(msg);
	}
}
